/**
 *  eventbuffer 客户端
 *  不调用 socket 创建套接字
 */

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <event2/bufferevent.h>
#include <event2/event.h>
#include <arpa/inet.h>


#define SERVER_PORT 	9090
#define SERVER_ADDR		"127.0.0.1"

// 读缓冲区回调
void readcb(struct bufferevent * bev, void * ctx)
{
	char data_buf[1024] = {0};
	bufferevent_read(bev, data_buf, 1024);

	printf("Recv data: %s\n", data_buf);

}

// 写缓冲区回调
void writecb(struct bufferevent * bev, void * ctx)
{
	printf("数据发送完成\n");
}



// 事件回调
void eventcb(struct bufferevent * bev, short what, void * ctx)
{
	if (what & BEV_EVENT_EOF)
    {
        printf("connection closed\n");  
    }
    else if(what & BEV_EVENT_ERROR)   
    {
        printf("some other error\n");
    }
	else if(what & BEV_EVENT_CONNECTED)
	{
		printf("已经连接到服务器\\(^o^)/...");
        return;
	}
    
    bufferevent_free(bev);    
    printf("buffevent 资源已经被释放...\n"); 
}

void read_terminal(evutil_socket_t fd, short what , void *arg)
{
	char data_buf[1024] = {0};
	int len = read(fd, data_buf, 1024);	

	struct bufferevent * bev = (struct bufferevent *)arg;
	bufferevent_write(bev, data_buf, len);
}


int main(){


	struct event_base *base = event_base_new();

	
	// fd 为 -1 ， 后面设置文件描述符
	struct bufferevent *bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);

	struct sockaddr_in sAddr;
	int socklen = sizeof(sAddr);
	memset(&sAddr, 0, socklen);
	sAddr.sin_family = AF_INET;
	sAddr.sin_port = htons(SERVER_PORT);
	inet_pton(AF_INET,SERVER_ADDR,&sAddr.sin_addr.s_addr);
	// 连接服务器
	bufferevent_socket_connect(bev, (struct sockaddr *)&sAddr, socklen); // 前面没有设置文件描述符，在此位bufferevent设置套接字(非阻塞)

	// 设置回调
	bufferevent_setcb(bev, readcb, writecb, eventcb, NULL);
	bufferevent_enable(bev, EV_READ);

	// 添加事件
	struct event *ev = event_new(base, STDIN_FILENO, EV_READ | EV_PERSIST, read_terminal, bev);
	event_add(ev, NULL);


	event_base_dispatch(base);

	event_free(ev);
	event_base_free(base);



	return 0;
}

